package fg.math;

/**
 * Interface for describing easing calculations. Stuff based on Robert Penner's
 * Easing Equations found at <code>http://www.robertpenner.com/easing/</code>.
 * Many thanks to him :)
 * 
 * @author robin
 * 
 */
public interface Easing {

	/**
	 * Calculates the specified easing.
	 * 
	 * @param t
	 *            the time (ms, frame, etc)
	 * @param b
	 *            the beginning value
	 * @param c
	 *            the value changed
	 * @param d
	 *            the duration
	 * @return eased value
	 */
	public float ease(float t, float b, float c, float d);

	/**
	 * Linear easing or no easing at all.
	 */
	public static final Easing LINEAR = new Easing() {
		public float ease(float t, float b, float c, float d) {
			return (c * t / d + b);
		}
	};

	// / Quadratic easing t^2 / //

	/**
	 * Quadratic easing in - Acceleration
	 */
	public static final Easing QUAD_IN = new Easing() {
		public float ease(float t, float b, float c, float d) {
			return (c * (t /= d) * t + b);
		}
	};

	/**
	 * Quadratic easing out - Deceleration
	 */
	public static final Easing QUAD_OUT = new Easing() {
		public float ease(float t, float b, float c, float d) {
			return (-c * (t /= d) * (t - 2) + b);
		}
	};

	/**
	 * Quadratic easing in / out - Acceleration until halfway then Decceleration
	 */
	public static final Easing QUAD_IN_OUT = new Easing() {
		public float ease(float t, float b, float c, float d) {
			if ((t /= d / 2) < 1f)
				return (c / 2 * t * t + b);
			return (-c / 2 * ((--t) * (t - 2f) - 1) + b);
		}
	};

	// / Cubic easing t^3 / //

	/**
	 * Quadratic easing in - Acceleration
	 */
	public static final Easing CUBIC_IN = new Easing() {
		public float ease(float t, float b, float c, float d) {
			return (c * (t /= d) * t * t + b);
		}
	};

	/**
	 * Quadratic easing out - Deceleration
	 */
	public static final Easing CUBIC_OUT = new Easing() {
		public float ease(float t, float b, float c, float d) {
			return (c * ((t = t / d - 1) * t * t + 1) + b);
		}
	};

	/**
	 * Quadratic easing in / out - Acceleration until halfway then Decceleration
	 */
	public static final Easing CUBIC_IN_OUT = new Easing() {
		public float ease(float t, float b, float c, float d) {
			if ((t /= d / 2) < 1f)
				return (c / 2 * t * t * t + b);
			return (c / 2 * ((t -= 2) * t * t + 2) + b);
		}
	};
}
